
/**
 * @author Daniel Weber
 * Liefert alle statischen Hilfsmethoden, die meist in mehreren Klassen benötigt werden.
 */
import java.util.Random;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

public class system {

    static int w; //Abmessungen des Screens
    static int h;
    static byte anchor = Graphics.TOP | Graphics.LEFT;
    static Random random;
    static Font font;
//----------Preloader-----------------------------------------------------------
    //Wird true wenn die Daten fertig geladen wurden.
    public static boolean preloaderReady = false;

    /**
     * Lädt einmalig alle relevanten Daten zu Vorbereitung des Spiels.
     */
    public static void preloader() {
        font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL);
        random = new Random();
        //alle Bilder werden geladen
        system.loadImages();
        if (!SpeicherInterface.check("highscores")) {
            int[] liste = new int[8];
            SpeicherInterface.writeIntegerArray("highscores", liste);
        } else if (SpeicherInterface.readIntegerArray("highscores").length != 8) {
            int[] liste = new int[8];
            SpeicherInterface.writeIntegerArray("highscores", liste);
        }
        Game.higscoreListe = SpeicherInterface.readIntegerArray("highscores");
        new InputStreams();
        Game.Init();
        preloaderReady = true;
    }
//-------------Menü-------------------------------------------------------------
    static String[] entry = {
        "< Einzelspieler >",
        "< Mehrspieler >"
    };
    static int index = 0;

    /**
     * Zeichnet das Spielmenü
     * Bei wide=true wird das Menü horizontal gezeichnet.
     * @param g
     * @param wide
     */
    public static void drawMenu(Graphics g, boolean wide) {
        int pNr = 0;
        for (int i = 0; i < 4; i++) {
            if (Game.bPlayer[i]) {
                pNr++;
            }
        }
        //Spielerauswahlmenü
        if (Game.bChoice) {
            if (ActionCanvas.bFire && pNr >= 2) {
                ActionCanvas.bFire = false;
                for (int i = 0; i < 4; i++) {
                    Game.spielerPunkte[i] = 0;
                }
                Game.iSpielerZahl = pNr;
                Game.bChoice = false;
                Game.bMenu = false;
                Game.Init();
                Game.state[0] = Game.PLAY;
            } else {
                if (ActionCanvas.bGameA) {
                    ActionCanvas.bGameA = false;
                    Game.bPlayer[0] = !Game.bPlayer[0];
                }
                if (ActionCanvas.bGameB) {
                    ActionCanvas.bGameB = false;
                    Game.bPlayer[1] = !Game.bPlayer[1];
                }
                if (ActionCanvas.bGameC) {
                    ActionCanvas.bGameC = false;
                    Game.bPlayer[2] = !Game.bPlayer[2];
                }
                if (ActionCanvas.bGameD) {
                    ActionCanvas.bGameD = false;
                    Game.bPlayer[3] = !Game.bPlayer[3];
                }
                system.clearScreen(0x00000000, g);
                int x = w / 2 - Game.gMan[0].getWidth() / 2, y = h / 2 - Game.gMan[0].getHeight() / 2;
                for (int i = 0; i < 4; i++) {
                    if (i == 0) {
                        Game.gMan[i].setPosition(x - 60, y - 60);
                    } else if (i == 1) {
                        Game.gMan[i].setPosition(x + 60, y - 60);
                    } else if (i == 2) {
                        Game.gMan[i].setPosition(x - 60, y + 60);
                    } else if (i == 3) {
                        Game.gMan[i].setPosition(x + 60, y + 60);
                    }
                    if (Game.bPlayer[i]) {
                        Game.gMan[i].nextFrame();
                    } else {
                        Game.gMan[i].setFrame(1);
                    }
                    Game.gMan[i].setVisible(true);
                    Game.gMan[i].paint(g);
                }
            }
            //Hauptmenü
        } else if (wide) {
            int y = system.h / 2 - system.font.stringWidth(entry[index]) / 2;
            int x = system.w / 2;
            int width = system.font.stringWidth(entry[index]);
            int height = system.font.getHeight();
            Image img = Image.createImage(width, height);
            Graphics gr = img.getGraphics();
            gr.setFont(system.font);
            gr.setColor(0, 0, 0);
            gr.drawString(entry[index], 0, 0, system.anchor);
            g.drawRegion(img, 0, 0, width, height, Sprite.TRANS_ROT90, x, y, system.anchor);
            if (ActionCanvas.bUp) {
                ActionCanvas.bUp = false;
                index--;
            }
            if (ActionCanvas.bDown) {
                ActionCanvas.bDown = false;
                index++;
            }
        } else {
            int x = system.w / 2 - system.font.stringWidth(entry[index]) / 2;
            int y = system.h * 2 / 3;
            int width = system.font.stringWidth(entry[index]);
            int height = system.font.getHeight();
            Image img = Image.createImage(width, height);
            Graphics gr = img.getGraphics();
            gr.setFont(system.font);
            gr.setColor(0, 0, 0);
            gr.drawString(entry[index], 0, 0, system.anchor);
            g.drawRegion(img, 0, 0, width, height, Sprite.TRANS_NONE, x, y, system.anchor);

            if (ActionCanvas.bLeft) {
                ActionCanvas.bLeft = false;
                index--;
            }
            if (ActionCanvas.bRight) {
                ActionCanvas.bRight = false;
                index++;
            }
        }

        if (index < 0) {
            index = entry.length - 1;
        }
        if (index > entry.length - 1) {
            index = 0;
        }

        if (ActionCanvas.bFire) {
            ActionCanvas.bFire = false;
            switch (index) {
                case 0:
                    Game.iSpielerZahl = 1;
                    Game.bPlayer[0]=true;
                    Game.bPlayer[1]=false;
                    Game.bPlayer[2]=false;
                    Game.bPlayer[3]=false;
                    Game.bMenu = false;
                    Game.Init();
                    Game.state[0] = Game.PLAY;
                    break;
                case 1:
                    Game.bChoice = true;
                    break;
            }
        }

    }


//--------------------Parallax-Scrolling----------------------------------------
    static boolean init = true;
    static int[] bg_y;
    static int[] bg_h;
    static int actorOldyt = 0;

    public static void drawParallaxBackground(Graphics g) {

        if (init) {
            init = false;
            bg_y = new int[2];
            bg_h = new int[2];
            bg_h[0] = img[city1].getHeight();
            bg_h[1] = img[city2].getHeight();
        }

        //Positionsänderung des Spielers ermitteln
        int diffY = Game.gMan[Game.iFrontMan].getY() - actorOldyt;
        actorOldyt = Game.gMan[Game.iFrontMan].getY();

        //Parralax-Ebene verschieben
        for (int i = 0; i < diffY; i++) {

            if (i % 4 == 0) {
                bg_y[0]++;
            }
            if (i % 2 == 0) {
                bg_y[1]++;
            }

            //Grenzen für Referenzpunkt
            for (int n = 0; n < 2; n++) {
                if (bg_y[n] > bg_h[n]) {
                    bg_y[n] = 0;
                }
                if (bg_y[n] < 0) {
                    bg_y[n] = bg_h[n];
                }
            }
        }
        g.drawImage(img[sun], 0, 0, anchor);
        g.drawImage(img[city1], 0, -bg_y[0], anchor);
        g.drawImage(img[city1], 0, -bg_y[0] + bg_h[0], anchor);
        g.drawImage(img[city2], 0, -bg_y[1], anchor);
        g.drawImage(img[city2], 0, -bg_y[1] + bg_h[1], anchor);
    }
//------------Systeminfos-------------------------------------------------------
    static int fps;

    /**
     * Zeichnet die Bildwiederholungsrate
     */
    public static void drawFPS(Graphics g) {
        quickText("FPS: " + fps, system.w - 10, system.h / 20, g);
    }
//-----------Load Images--------------------------------------------------------	
    static Image[] img;
    static byte mapPNG = 0;
    static byte splashScreenJPG = 1;
    static byte fontPNG = 2;
    static byte GMan0 = 3;
    static byte GMan1 = 4;
    static byte GMan2 = 5;
    static byte GMan3 = 6;
    static byte city1 = 7;
    static byte city2 = 8;
    static byte sun = 9;
    static byte imgAnz = 10;

    public static void loadImages() {
        try {
            img = new Image[imgAnz];
            img[mapPNG] = Image.createImage("/img_Tiles.png");
            img[splashScreenJPG] = Image.createImage("/img_Splash.jpg");
            img[fontPNG] = Image.createImage("/img_Font.png");
            img[GMan0] = Image.createImage("/img_GMan0.png");
            img[GMan1] = Image.createImage("/img_GMan1.png");
            img[GMan2] = Image.createImage("/img_GMan2.png");
            img[GMan3] = Image.createImage("/img_GMan3.png");
            img[city1] = Image.createImage("/img_City1.png");
            img[city2] = Image.createImage("/img_City2.png");
            img[sun] = Image.createImage("/img_Sun.jpg");
        } catch (Exception e) {
            System.out.println("Bildladefehler!");
        }
    }
//---------------Outlines-------------------------------------------------------
    static int fontW = 14; //incl. 1 Pixel Space
    static int fontH = 8; //incl. 2 Pixel Space

    /**
     * Besonders performantes Zeichnen von horizontalem Text.
     * @param txt
     * @param x
     * @param y
     * @param g
     */
    public static void quickText(String txt, int x, int y, Graphics g) {

        txt = txt.toUpperCase();
        char ca[] = txt.toCharArray();
        for (int i = 0; i < ca.length; i++) {
            byte fontFrame = (byte) (ca[i] - 0x2B);
            g.setClip(x, y, fontW, fontH);
            g.drawImage(img[fontPNG], x, y - fontFrame * fontH, system.anchor);
            g.setClip(0, 0, system.w, system.h);
            y += fontH;
        }
    }
//----------bool----------------------------------------------------------------

    /**
     * Gibt zurück, ob das Zeichen eine Ziffer ist.
     * @param c
     * @return
     */
    public static boolean isInt(char c) {
        return (c == '0' || c == '1'
                || c == '2' || c == '3'
                || c == '4' || c == '5'
                || c == '6' || c == '7'
                || c == '8' || c == '9');
    }
//----------Timer---------------------------------------------------------------
    static byte timer = 0;

    public static void pumpTimer() {
        timer++;
        if (timer > 1024) {
            timer = 0;
        }
    }

    /**
     * Gibt für eine Menge an Wiederholungen pro Sekunde true zurück
     */
    public static boolean intervall(int freq) {
        int f = 1024 / freq;
        return (timer % f == 0);
    }
//-----Random-Werte-------------------------------------------------------------

    /**
     * Gibt einen Randomdwert zwischen 0 und |grenze| zurück, incl. 0 und grenze
     */
    public static int getRnd(int grenze) {
        return (random.nextInt() >>> 1) % (grenze + 1);
    }

//-----Layer-Koordinaten--------------------------------------------------------
    /**
     * Gibt die Horizontale Koordinate eines GMan zurück, die von der Kamera weiterverarbeitet werden kann.
     * @param spr
     * @return
     */
    public static int getXLayer(Sprite spr) {
        return spr.getY() + spr.getHeight() / 2 - h / 2;
    }
//-----Clear Screen-------------------------------------------------------------	

    /**
     * Leert den Framebuffer.
     * @param bgColor
     * @param g
     */
    public static void clearScreen(int bgColor, Graphics g) {
        g.setColor(bgColor);
        g.fillRect(0, 0, system.w, system.h);
    }
//------------------------------------------------------------------------------	
}
